/*
 * RSProjectionTechnique.cpp
 *
 *  Created on: 2010/03/15
 *      Author: alexandre
 */

#include "RSProjectionTechnique.h"
#include "RSProjectionTechniqueElement.h"
#include <QMatrix4x4>

namespace Realsphere {

    RSProjectionTechnique::RSProjectionTechnique () :
            RSTechniqueCommon ()
    {
        mProjectionElement = NULL;
    }

    RSProjectionTechnique::~RSProjectionTechnique ()
    {
        mProjectionElement = NULL;
    }

    QMatrix4x4 RSProjectionTechnique::ProjectionMatrix() const {
        QMatrix4x4 projection;
        if ( mProjectionElement == NULL )
            return projection;

        return mProjectionElement->ProjectionMatrix ();
    }

    RSProjectionElementType RSProjectionTechnique::ProjectionType() const {
        if ( mProjectionElement == NULL )
            return RS_PROJECTION_ELEMENT_UNKNOWN;

        return mProjectionElement->ProjectionType();
    }

    RSProjectionTechniqueElement* RSProjectionTechnique::ProjectionElement() const {
        return mProjectionElement;
    }

    RSError RSProjectionTechnique::SetProjectionElement ( RSProjectionTechniqueElement* rProjectionElement ) {
        RSError error = AddChildElement ( rProjectionElement );
        return error;
    }

    RSError RSProjectionTechnique::BeforeAddChildElement ( RSElement* rChild ) {

        RSError error = RSTechniqueCommon::BeforeAddChildElement ( rChild );

        if ( rChild->InstanceOf( RS_PROJECTION_TECHNIQUE_ELEMENT_CLASS ) ) {
            error = RS_NO_ERROR;
        }

        return error;
    }

    bool RSProjectionTechnique::AfterAddChildElement ( RSElement* rChild ) {

        bool handled = RSTechniqueCommon::AfterAddChildElement ( rChild );

        if ( handled ) {
            if ( rChild->InstanceOf ( RS_PROJECTION_TECHNIQUE_ELEMENT_CLASS ) ) {

                if ( mProjectionElement != NULL )
                    RemoveChildElement ( mProjectionElement );

                mProjectionElement = RSProjectionElementTechniqueCast(rChild);
                handled = true;

                emit ProjectioElementAdded ( mProjectionElement );
            }
        }

        return handled;
    }

    bool RSProjectionTechnique::AfterRemoveChildElement ( RSElement* rChild ) {

        bool handled = RSTechniqueCommon::AfterRemoveChildElement ( rChild );

        if ( handled ) {
            if ( rChild->InstanceOf ( RS_PROJECTION_TECHNIQUE_ELEMENT_CLASS ) ) {

                RSProjectionTechniqueElement* projection_element = RSProjectionElementTechniqueCast(rChild);
                mProjectionElement = NULL;
                handled = true;

                emit ProjectioElementRemoved ( projection_element );
            }
        }

        return handled;
    }


}
